package cn.mg.framework.response;

import cn.mg.framework.annotations.ResponseResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * @author hezhaoming
 * @date 2019-11-04
 */
@Slf4j
@Component
public class ResponseResultInterceptor implements HandlerInterceptor {

    public static final String RESPONSE_RESULT = "RESPONSE-RESULT";

    private static final Map<String, Object> classMps = new HashMap<String,Object>();

    private static final Map<String, Object> methodMps = new HashMap<String,Object>();

    /**
     * 反射损耗性能 考虑用map做一层缓存优化
     *
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod) {
            final HandlerMethod handlerMethod = (HandlerMethod) handler;
            final Class<?> clazz = handlerMethod.getBeanType();
            final Method method = handlerMethod.getMethod();
            boolean b = true;

            if (classMps.containsKey(clazz.getName())) {
                b = false;
                request.setAttribute(RESPONSE_RESULT, classMps.get(clazz.getName()));
            } else {
                //判断类上是否有该注解
                if (clazz.isAnnotationPresent(ResponseResult.class)) {
                    b = false;
                    ResponseResult annotation = clazz.getAnnotation(ResponseResult.class);
                    classMps.put(clazz.getName(), annotation);
                    request.setAttribute(RESPONSE_RESULT, annotation);
                }
            }
            //如果类上没有注解 则检查方法上是否需要统一返回数据格式
            if (b) {
                if (methodMps.containsKey(method.getName())) {
                    request.setAttribute(RESPONSE_RESULT, methodMps.get(method.getName()));
                } else {
                    if (method.isAnnotationPresent(ResponseResult.class)) {
                        ResponseResult annotation = method.getAnnotation(ResponseResult.class);
                        methodMps.put(method.getName(), annotation);
                        request.setAttribute(RESPONSE_RESULT, annotation);
                    }
                }
            }
        }
        return true;
    }
}
